清羽AI正在绞尽脑汁想思路ING···
清羽のAI摘要
GLM-4-Flash

碎碎念

距离前往上海工作的日子只剩两三天了,心里总有点彷徨和迷失的感觉。转眼之间,就要从学生身份走向社会了,心态上似乎还没完全跟上这种转变。不过人生总归是要往前走的吧,希望自己能慢慢适应新的生活。

最近我迷上了 SSO,于是自建了一个 Casdoor,算是实现了自己的“通行证”。凡是能接入登录的地方我都尽量接上,实在没法直接支持的,我就会用 Nginx 来做一层鉴权:一方面相当于多加了一层保护,另一方面有些站点确实不太适合完全对外公开,QAQ

其实我一直想给评论系统接入更多的登录方式,但无奈 Artalk 官方几乎不再更新,我也懒得去翻源码。后来偶然发现它内置了一个 auth0 验证方式,还支持自定义接口,这让我突然来了兴趣。研究一番后,我灵机一动,干脆用“赛博飞线”的方法,把 Casdoor 强行接到了它的接口上。这样一来,就能通过 Casdoor 来做社交登录,再借助 Casdoor 本身提供的多平台对接,把 GitHubGoogleGitee等账号也串联起来。

最终的效果还挺满意的,下面就来记录一下我是怎么实现的吧!

介绍

Casdoor

Casdoor 是一个开源的统一身份认证平台,定位类似于“通行证中心”。通过标准化的协议和接口,把分散在不同系统中的用户认证集中起来管理,让登录这件事变得更简单。对于个人开发者来说,Casdoor 可以在自建环境下快速实现一个完整的SSO(单点登录)方案,而不需要依赖第三方的封闭服务。

账号统一绑定到通行证上

它的核心理念是“统一”,不论是账号体系、登录入口还是第三方应用接入,都可以在 Casdoor 中完成整合。比如,你可以只在 Casdoor 中注册和管理用户,其他业务系统则直接通过 Casdoor 来校验身份。这样一来,用户只需要在 Casdoor 登录一次,就能无缝进入所有已接入的应用,避免了重复输入账号密码的繁琐。

Casdoor 还提供了丰富的第三方平台对接能力。除了本地用户系统外,它原生支持 GitHubGoogleFacebookGitee 等常见平台的 OAuth 登录,甚至也能接入自定义的认证源。这种开放性让它不仅适用于企业内部系统,也适用于个人网站或社区类应用,特别适合那些想要统一社交登录入口的场景。

casdoor

在部署和使用上,Casdoor 相对轻量。它提供了 Docker 镜像,几乎开箱即用,配置好数据库后就能运行。同时,它有一个可视化的管理后台,方便管理员配置应用、调整认证方式、管理用户信息。对于开发者来说,Casdoor 提供了多语言 SDK 和标准的 RESTful API,可以轻松与前后端项目对接。

选择什么?

该说不说,虽然 Casdoor 的功能确实很完善,但界面真的是丑,配置也比较繁琐,而且有不少功能在我的场景里根本用不上。在开发过程中,我其实还找到过两个类似的项目,一个是 LogTo,另一个就是 Casdoor。最终之所以选择了 Casdoor,是因为它自带用户页面,用户可以自己绑定第三方应用,从而完成登录系统的整合。相比之下,LogTo 虽然界面更美观、使用体验更好,但一方面资源占用更高,另一方面缺少用户中心这个关键功能,所以最后还是被我淘汰了。

Casdoor 更像是一个“身份中枢”。它帮你把复杂的用户认证逻辑都收口在一个地方,既能统一管理账号,又能开放扩展到不同系统和平台。无论是个人博客、开源社区,还是企业级内网系统,都能从中受益。

教程

配置

ArtalkCasdoor 的部署部分我就不展开了。我个人觉得比较麻烦的还是在 Casdoor 的配置上。前面也提到过,Casdoor 的优点是配置项非常多,可以满足各种自定义需求,但缺点同样也在于配置项过于繁杂,让人很难一个人把所有细节都摸透。

所以这里我就按照我自己的实际配置,来讲一讲该如何正确地配置并使用 Casdoor,希望能给同样想折腾的人一点参考。

组织

Casdoor 里,不同组织之间的用户是完全隔离的。如果你是个人使用,其实没必要建太多组织,保持一个就够了。这样账号才能互通,不然你会发现,同一个人去不同的平台还得重新注册,反而增加麻烦。除了默认的 built-in 组织之外,建议额外新建一个,比如我这里就建了一个叫 LiuShen 的组织:

创建组织

这里有一点要特别注意:千万不要直接使用 built-in 组织。因为在这个组织里,所有成员默认都有管理员权限,如果配置不当,很可能会导致数据泄露。

在用户个人页面里的配置项,大多数只是个人信息相关,自己修改不会有太大问题。但从涉及权限的地方开始,最好保持默认,不要随便改。比如你可以关闭一些非必要的字段展示,不过像 ID、昵称这种关键属性最好不要隐藏。像学历、门牌号这种用户一般不会填的字段,你完全可以关掉。

第三方绑定信息

如果你准备对接第三方系统,千万别把 Properties 数据项关掉,否则用户绑定的三方账号信息无法显示,虽然不影响功能,但是影响美观。下面的几个选项里,除了倒数第三个之外,最后两个都需要额外应用支持。比如多因素认证需要接码平台,一般场景用不上,可以直接删掉。

再往下就是一些美化相关的配置了。LDAP 服务器如果你用不上,也完全可以忽略。

证书

在创建好组织之后,接下来需要去菜单中的 身份认证 子菜单里,找到证书(Certificates),为当前组织新建一张证书。这一步的作用主要是用来加密数据,比如 JWT 的签发和验证、OAuth 登录过程中的信息传递,都依赖这个证书,一个组织可以共用一张证书,当然你也可以一个应用一张,我推荐前者。

证书必须和你的组织绑定在一起,只有这样,该组织下的应用才能使用它来完成认证,证书类型一般选择 JWT。系统会自动帮你生成一对公钥和私钥,公钥可以对外公开,供其他应用验证签名;私钥则只能保存在Casdoor内部,用来签发令牌,不要对外公开。

另外,证书创建完成后,可以在配置页面看到对应的公钥和私钥。一般来说不需要修改,但如果你有更严格的安全要求,也可以自行导入自有的密钥对。需要提醒的是,千万不要随意更换或删除证书,否则现有的登录会话和签发的令牌都会失效,导致用户无法正常登录。

完成证书配置后,后续无论是OAuthOIDC还是SAML的对接,都会依赖于这张证书来保证数据的安全和可信。

提供商

Casdoor 中,一个非常关键的功能就是对接不同的 提供商。通过配置这些提供商,你可以扩展系统的能力,比如使用存储提供商来保存用户头像,接入极验验证码来增强安全性,或者对接 OAuth2.0、邮箱 SMTP 等方式,从而实现邮箱登录、GitHub 等平台登录。除此之外,还能在请求过于频繁时启用验证码校验,用来防止恶意攻击,整体上功能非常完善。

对接三方登录

配置提供商时,建议优先添加你需要的第三方服务,再去创建应用。这样在应用配置阶段,直接就能把相关提供商挂上去,效果会更加直观,也能避免重复修改配置,其中所有应用的回调地址均为:

1
https://auth.liushen.fun/callback

具体怎么添加提供商我这里就不展开了,因为不同服务商的配置方式会略有差异,但大体上流程类似:选择提供商类型 → 填写必要的参数(如 Client IDClient SecretEndpoint 等)→ 保存即可。后续应用在调用时,就能直接复用这些提供商配置。

应用

完成组织、证书和提供商的准备之后,就可以正式创建 应用(Applications) 了。在创建应用时要留意一个小细节:当你在上方选择组织后,证书列表有时不会自动刷新,可能看不到当前组织下的证书。这时只需要先保存应用,再退出重新进入编辑页面,就能正常看到并选择对应证书了。

在应用配置里,最关键的部分是 登录方式界面。界面这块主要是样式定制,可以根据个人喜好去改;而登录方式则直接影响到用户能以怎样的方式进入系统。我个人建议至少启用三种:

登录方式

分别是 密码登录验证码登录Web 身份认证。这三种方式都不依赖于额外的外部应用,只要配置好 SMTP,就能实现相对完整的验证体验,既保证了基础可用性,也能满足一些安全需求。

接下来是提供商的挂载。这里需要根据你的实际需求来选择,比如如果上面启用了验证码登录,那么就必须添加一个 Email 类型的提供商,否则验证码功能无法生效。同样地,在注册项配置中,如果你没有打算做电话验证,最好直接删掉相关字段,避免用户界面出现无效的输入项。

这样配置下来,一个相对完善又干净的应用登录系统就成型了,下面我们将其强行对接到Artalk上吧!

强行兼容

后端

要实现兼容,首先得明确 Auth0Casdoor 中几个关键接口的对应关系:

1
2
3
4
5
6
7
8
9
# ===== Auth0 接口 =====
AUTH0_AUTHORIZE_URL=https://your-auth0-domain/authorize # 用户跳转登录页面,获取授权码
AUTH0_TOKEN_URL=https://your-auth0-domain/oauth/token # 授权码换取 Token
AUTH0_USERINFO_URL=https://your-auth0-domain/userinfo # 获取用户基本信息

# ===== Casdoor 对应接口 =====
CASDOOR_AUTHORIZE_URL=https://your-casdoor-domain/login/oauth/authorize # 用户跳转 Casdoor 登录页面
CASDOOR_TOKEN_URL=https://your-casdoor-domain/api/login/oauth/access_token # 授权码换取 Token
CASDOOR_USERINFO_URL=https://your-casdoor-domain/api/user # 获取用户基本信息

核心就是这三个接口。其中第二个 /oauth/token 必须使用 POST 请求,而 authorizeuserinfo 则相对简单。既然目标是“赛博飞线”,那就直接通过 301 重定向或反向代理来处理。我这里选用 301 重定向来完成第一个和第三个接口的转发:

重定向

这样可以保证参数完整保留,把 Auth0 的请求地址直接映射到 Casdoor 的接口上,实现无缝跳转和用户信息获取。

至于第二个接口,由于涉及到 POST,没办法用重定向来解决,所以需要通过反向代理来中转请求:

反向代理

完成这两个步骤之后,接口层面就已经基本对齐了。接下来只需要在 Artalk 后台的社交登录配置里,把 IDSecret 和接口域名填上:

Artalk配置

保存并测试后,就能成功通过 Casdoor 登录了。

前端

虽然后端已经把 Casdoor 接入好了,但前端仍然显示 Auth0 官方图标,确实不太美观,所以我决定把它替换掉。先从数据源下手:按 F12 打开调试工具,很容易能找到一个 Providers 接口,里面列出了所有社交登录提供商:

provider接口

定位到该请求的 URL 之后,我选择在 Nginx 层拦截这条请求并返回自定义的 JSON,这样前端拿到的就是我定制的图标和名称。观察后发现 1Panel 的反向代理配置位于站点配置最底部的 ./proxy/*.conf 文件里,所以我们只需要在该目录下任意位置添加一个新的 server 配置片段即可(确保不要被后续配置覆盖)。下面是我实际用的片段(可直接放到站点对应的 .conf 文件里):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {
listen 80 ;
listen 443 ssl ;
server_name atk.liushen.fun;
index index.php index.html index.htm default.php default.htm default.html;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
access_log /www/sites/atk.liushen.fun/log/access.log main;
error_log /www/sites/atk.liushen.fun/log/error.log;
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
return 404;
}
+ # 拦截 Providers 请求并返回自定义 providers.json
+ location = /api/v2/conf/auth/providers {
+ default_type application/json;
+ alias /www/sites/atk.liushen.fun/index/providers.json;
+
+ # 开放 CORS(保证前端可以跨域请求)
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
+ add_header 'Access-Control-Allow-Headers' '*' always;
+
+ # 处理预检请求
+ if ($request_method = OPTIONS) {
+ add_header 'Access-Control-Max-Age' 1728000;
+ add_header 'Content-Type' 'text/plain; charset=UTF-8';
+ add_header 'Content-Length' 0;
+ return 204;
+ }
+
+ # 浏览器缓存 6 小时
+ add_header Cache-Control "public, max-age=21600";
+ }

在对应目录创建 providers.json,内容示例我也放出来了,按需改 labelpathicon 即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"providers": [{
"name": "email",
"label": "邮箱密码登录",
"path": "",
"icon": "https://p.liiiu.cn/i/2025/09/16/68c97ab730be7.webp"
}, {
"name": "auth0",
"label": "清羽通行证登录",
"path": "/api/v2/auth/auth0",
"icon": "https://p.liiiu.cn/i/2025/09/16/68c97ac3a4b3b.webp"
}, {
"name": "skip",
"label": "Skip",
"path": "",
"icon": "https://p.liiiu.cn/i/2025/09/16/68c97acf486fe.webp"
}],
"anonymous": true
}

几个要点提醒:

  • 把上面的 providers.json 放在 alias 指定的路径下,并确保 nginx 用户可读。
  • 修改完成后执行 nginx -s reload 重载配置,当然1Panel点击保存即可。
  • 如果前端仍显示旧图标,清一下浏览器缓存或确认 Cache-Control 是否生效。

最终效果就是前端的社交登录按钮会显示我自定义的图标和文案,Artalk 的登录入口看起来也更统一、更好看了。欢迎大家试试用通行证登录评论系统!

总结

这一路把CasdoorAuth0的接口适配、后端重定向与反代处理、前端providers.json的替换方案逐步走通,从零碎的实验到最后跑通社交登录,算是把一套看似复杂的流程给串了起来。后端保证了接口层的兼容,前端则通过定制数据源让用户界面更美观统一,整体方案也更易于维护和扩展。到这一步,算是完整地实现了从“能用”到“好用”的过渡。

写到这里,也该收个尾了。再过两天就要动身去上海,开启全新的人生篇章。希望一切顺利,代码稳定,生活也同样流畅。 🚀

每日一图

图片来自哲风壁纸

人生